home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / ge_cool.lha / GE_COOL2.1 / src / Association / Association.C next >
C/C++ Source or Header  |  1992-06-29  |  11KB  |  289 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12.  
  13. #include <cool/Association.h>
  14.  
  15. // CoolAssociation -- Empty constructor for the CoolAssociation class
  16. // Input:         None
  17. // Output:        None
  18.  
  19. template <class Ktype, class Vtype>
  20. CoolAssociation<Ktype,Vtype>::CoolAssociation<Ktype,Vtype> () {
  21.   if (this->compare_keys_s == NULL)        // If no compare function
  22.     compare_keys_s=&CoolAssociation<Ktype,Vtype>_keys_eql; // Set to default equal
  23.   if (this->compare_values_s == NULL)        // If no compare function
  24.     compare_values_s = &CoolAssociation<Ktype,Vtype>_values_eql; // Set to default
  25. }
  26.  
  27.  
  28. // CoolAssociation -- constructor that specifies number of elements
  29. // Input:         Number of elements of Type T
  30. // Output:        None
  31.  
  32. template <class Ktype, class Vtype>
  33. CoolAssociation<Ktype,Vtype>::CoolAssociation<Ktype,Vtype> (unsigned long n)
  34.  : CoolVector<CoolPair<Ktype,Vtype>>(n)
  35. {
  36.   if (this->compare_keys_s == NULL)        // If no compare function
  37.     compare_keys_s=&CoolAssociation<Ktype,Vtype>_keys_eql; // Set to default equal
  38.   if (this->compare_values_s == NULL)        // If no compare function
  39.     compare_values_s = &CoolAssociation<Ktype,Vtype>_values_eql; // Set to default
  40. }
  41.  
  42.  
  43. // CoolAssociation -- constructor that specifies number of elements and storage
  44. // Input:         Pointer to storage and number of elements of Type T
  45. // Output:        None
  46.  
  47. template <class Ktype, class Vtype>
  48. CoolAssociation<Ktype,Vtype>::CoolAssociation<Ktype,Vtype> (void* s,unsigned long n)
  49.  : CoolVector<CoolPair<Ktype,Vtype>>(s,n)
  50. {
  51.   if (this->compare_keys_s == NULL)        // If no compare function
  52.     compare_keys_s=&CoolAssociation<Ktype,Vtype>_keys_eql; // Set to default equal
  53.   if (this->compare_values_s == NULL)        // If no compare function
  54.     compare_values_s = &CoolAssociation<Ktype,Vtype>_values_eql; // Set to default
  55. }
  56.  
  57.  
  58. // CoolAssociation -- constructor for reference to another CoolAssociation object
  59. // Input:         CoolAssociation reference
  60. // Output:        None
  61.  
  62. template <class Ktype, class Vtype>
  63. CoolAssociation<Ktype,Vtype>::CoolAssociation<Ktype,Vtype>
  64.                          (const CoolAssociation<Ktype,Vtype>& a)
  65.  : CoolVector<CoolPair<Ktype,Vtype>>(a)
  66. {
  67.   if (this->compare_keys_s == NULL)        // If no compare function
  68.     compare_keys_s=&CoolAssociation<Ktype,Vtype>_keys_eql; // Set to default equal
  69.   if (this->compare_values_s == NULL)        // If no compare function
  70.     compare_values_s = &CoolAssociation<Ktype,Vtype>_values_eql; // Set to default
  71. }
  72.  
  73.  
  74. // CoolAssociation -- Destructor (not inline because it's virtual)
  75. // Input:         None
  76. // Output:        None
  77.  
  78. template <class Ktype, class Vtype>
  79. CoolAssociation<Ktype,Vtype>::~CoolAssociation<Ktype,Vtype> () {;}
  80.  
  81.  
  82. // set_key_compare -- Set the compare function for the key of the pair
  83. // Input:             Pointer to new function
  84. // Output:            None
  85.  
  86. template <class Ktype, class Vtype>
  87. void CoolAssociation<Ktype,Vtype>::set_key_compare(CoolAssociation<Ktype,Vtype>_Key_Compare cf) {
  88.   if (cf == NULL)
  89.     this->compare_keys_s=&CoolAssociation<Ktype,Vtype>_keys_eql; // Default equal   
  90.   else
  91.     this->compare_keys_s = cf;
  92. }
  93.  
  94. // set_value_compare -- Set the compare function for the value of the pair
  95. // Input:               Pointer to new function
  96. // Output:              None
  97.  
  98. template <class Ktype, class Vtype>
  99. void CoolAssociation<Ktype,Vtype>::set_value_compare(CoolAssociation<Ktype,Vtype>_Value_Compare cf) {
  100.   if (cf == NULL)
  101.     this->compare_values_s = &CoolAssociation<Ktype,Vtype>_values_eql; // Default
  102.   else
  103.     this->compare_values_s = cf;
  104. }
  105.  
  106. // find -- Find first occurence of element in an CoolAssociation
  107. // Input:  Element value searching for
  108. // Output: TRUE/FALSE; current_position updated when success
  109.  
  110. template <class Ktype, class Vtype>
  111. Boolean CoolAssociation<Ktype,Vtype>::find (const Ktype& key) {
  112.   for (long i = this->number_elements -1; i >= 0; i--) // Search most recent first
  113.     if ((*this->compare_keys_s)(this->data[i].get_first(), key) == TRUE) {
  114.       this->curpos = i;                // Update current position if found
  115.       return TRUE;                // Return success
  116.     }
  117.   return FALSE;                    // Return failure
  118. }
  119.  
  120.  
  121. // get -- Get the associated value for a key in the CoolAssociation; return TRUE 
  122. //        and modify the given value variable if the key is found, otherwise 
  123. //        return FALSE and do not modify the value variable
  124. // Input:  Reference to a key, reference to a value 
  125. // Output: TRUE or FALSE
  126.  
  127. template <class Ktype, class Vtype>
  128. Boolean CoolAssociation<Ktype,Vtype>::get (const Ktype& key, Vtype& value) {
  129.   for (long i = this->number_elements -1; i >= 0; i--) // Search most recent first
  130.     if ((*this->compare_keys_s)(this->data[i].get_first(), key) == TRUE) {
  131.       value = this->data[i].second();        // Modify value only if found
  132.       return TRUE;                // Return success
  133.     }
  134.   return FALSE;                    // Return failure
  135. }
  136.  
  137.  
  138. // get_key -- Get the associated key for a value in the CoolAssociation; return 
  139. //            TRUE and modify the given key variable if the value is found, 
  140. //            otherwise return FALSE and do not modify the value variable
  141. // Input:     Reference to a value, reference to a key 
  142. // Output:    TRUE or FALSE
  143.  
  144. template <class Ktype, class Vtype>
  145. Boolean CoolAssociation<Ktype,Vtype>::get_key (const Vtype& value, Ktype& key) const {
  146.   for (long i = this->number_elements -1; i >= 0; i--) // Search most recent first
  147.    if ((*this->compare_values_s)(this->data[i].get_second(), value) == TRUE) {
  148.      key = this->data[i].first();        // Modify key only if found
  149.      return TRUE;                // Return success
  150.    }
  151.   return FALSE;                    // Return failure
  152. }
  153.  
  154.  
  155. // remove() -- Remove the pair at the current position and return the 
  156. //             value associated with that pair. Order is not preserved.
  157. // Input:      None.
  158. // Output:     Value of the removed pair, returned by value.
  159.  
  160. template <class Ktype, class Vtype>
  161. Vtype CoolAssociation<Ktype,Vtype>::remove () {
  162.   if (this->curpos == INVALID) this->remove_error("CoolPair");
  163.   Vtype value = this->data[this->curpos].second(); // Copy value removed
  164.   this->number_elements--;            // Update element count
  165.   if (this->curpos == this->number_elements)    // If past end of vector
  166.     this->curpos = INVALID;            // Invalidate current position
  167.   else                        // fill hole with last elmt
  168.     this->data[this->curpos] = this->data[this->number_elements]; 
  169.   return value;                    // Return removed item
  170. }
  171.  
  172. // remove (key) -- Search for key and remove the pair associated with it, 
  173. //                 if found, and return TRUE; otherwise return FALSE
  174. // Input:          Reference to a key
  175. // Output:         TRUE or FALSE
  176.  
  177. template <class Ktype, class Vtype>
  178. Boolean CoolAssociation<Ktype,Vtype>::remove (const Ktype& key) {
  179.   if (this->find(key)) {            // Search for pair with key
  180.     this->remove();                // Remove and reset curpos
  181.     return TRUE;                // Return success/failure
  182.   }
  183.   else
  184.     return FALSE;                
  185. }
  186.  
  187. // put -- Add a key-value pair to the CoolAssociation; if the key already exists,
  188. //        replace its associated value in the CoolAssociation; return TRUE if 
  189. //        successful
  190. // Input:  Reference to a key, reference to a value
  191. // Output: TRUE or FALSE
  192.  
  193. template <class Ktype, class Vtype>
  194. Boolean CoolAssociation<Ktype,Vtype>::put (const Ktype& key, const Vtype& value) {
  195.   for (long i = this->number_elements -1; i >= 0; i--) // Search most recent first
  196.     if ((*this->compare_keys_s)(this->data[i].get_first(), key) == TRUE) {
  197.       this->data[i].set_second(value);        // Update value if found
  198.       this->curpos = i;                // Update current position
  199.       return TRUE;                // Return success
  200.     }
  201.   if (this->number_elements == this->size) {    // If not enough memory    
  202.     if (this->alloc_size == INVALID) {        // If not allowed to grow
  203. #if ERROR_CHECKING
  204.       //RAISE (Error, SYM(CoolAssociation), SYM(Static_Size)),
  205.       printf ("CoolAssociation<%s,%s>::put(): Static-size CoolAssociation.\n",
  206.               #Ktype,#Vtype);
  207. #endif
  208.       return FALSE;                // Return failure flag
  209.     }
  210.     CoolPair<Ktype,Vtype>* temp;        // Temporary storage
  211.     if (this->growth_ratio != 0.0)         // If growth ratio specified
  212.       this->size = (long)(this->size * (1.0 + growth_ratio)); // New size
  213.     else
  214.       this->size += alloc_size;            // Update vector size
  215.     temp = new CoolPair<Ktype,Vtype>[this->size];    // Allocate storage
  216.     for (long i = 0; i < this->length(); i++)    // For all elements
  217.       temp[i] = this->data[i];            // Copy data
  218.     delete [] this->data;            // Free up old memory
  219.     this->data = temp;                // Assign new memory block
  220.   }
  221.   this->curpos = this->length();        // Set current position
  222.   this->data[this->length()].set_first(key);    // Set the key (first) value
  223.   this->data[this->length()].set_second(value); // Set the value (second)
  224.   this->number_elements++;            // Increment element count
  225.   return TRUE;                    // Return success status
  226. }
  227.  
  228.  
  229. // operator== -- Compare the elements of two CoolAssociations of Type Type using
  230. //               the Compare pointer to funtion (default is ==). If one 
  231. //               CoolAssociation has more elements than another CoolAssociation, 
  232. //               then result is FALSE
  233. // Input:        Reference to CoolAssociation object
  234. // Output:       TRUE/FALSE
  235.  
  236. template <class Ktype, class Vtype>
  237. Boolean CoolAssociation<Ktype,Vtype>::operator==
  238.         (const CoolAssociation<Ktype,Vtype>& a) const {
  239.   if (this->number_elements != a.number_elements) // If not same number
  240.     return FALSE;                  // Then not equal
  241.   for (long i = 0; i < this->number_elements; i++) { // For each element
  242.     for (long j = 0; j < a.number_elements; j++) {
  243.       if ((*this->compare_keys_s)(this->data[i].get_first(),
  244.                   a.data[j].get_first()) == TRUE) {
  245.     if ((*this->compare_values_s) (this->data[i].second(),
  246.                        a.data[j].second()) == TRUE)
  247.       goto match;                // Match
  248.     return FALSE;                // Values different
  249.       }
  250.     }
  251.     return FALSE;                // Key not found
  252.   match: ;
  253.   }
  254.   return TRUE;                    // All are equal
  255. }
  256.  
  257. // operator<< -- Overload the output operator for reference to CoolAssociation
  258. // Input:        ostream reference, CoolAssociation reference
  259. // Output:       CoolAssociation data is output to ostream
  260.  
  261. template <class Ktype, class Vtype> CoolAssociation {
  262. ostream& operator<< (ostream& os, const CoolAssociation<Ktype,Vtype>& v) {
  263.   return operator<< (os, (const CoolVector<CoolPair<Ktype,Vtype>>&) v);
  264. }}
  265.  
  266.  
  267. // keys_eql -- Compare two keys to see if they are equal using operator==
  268. // Input:      Two Ktype references
  269. // Output:     TRUE or FALSE
  270.  
  271. template <class Ktype, class Vtype> CoolAssociation {
  272.   Boolean CoolAssociation<Ktype,Vtype>_keys_eql (const Ktype& k1, const Ktype& k2) {
  273.     return (k1 == k2);
  274.   }
  275. }
  276.  
  277.  
  278. // values_eql -- Compare two values to see if they are equal using operator==
  279. // Input:        Two Vtype references
  280. // Output:       TRUE or FALSE
  281.  
  282. template <class Ktype, class Vtype> CoolAssociation {
  283.   Boolean CoolAssociation<Ktype,Vtype>_values_eql(const Vtype& v1,const Vtype& v2) {
  284.     return (v1 == v2);
  285.   }
  286. }
  287.  
  288.  
  289.